home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / loading / transform_symtab_copy.c < prev    next >
C/C++ Source or Header  |  1991-05-30  |  10KB  |  393 lines

  1. /* File: transform_symtab_copy.c - last edit:
  2.  * horton    Wed Mar 21 12:12:04 1990
  3.  * 
  4.  * Copyright (c) 1989 by Xerox Corporation. All rights reserved.
  5.  * Copyright (c) 1990 by Xerox Corporation. All rights reserved. */
  6.  
  7. /*
  8.  *    %M% %I% of %G%
  9.  *    %W%
  10.  */
  11. /* begincopyright
  12.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  13.   Use and copying of this software and preparation of derivative works based
  14.   upon this software are permitted. Any distribution of this software or
  15.   derivative works must comply with all applicable United States export
  16.   control laws. This software is made available AS IS, and Xerox Corporation
  17.   makes no warranty about the software, its performance or its conformity to
  18.   any specification. Any person obtaining a copy of this software is requested
  19.   to send their name and post office or electronic mail address to:
  20.     PCR Coordinator
  21.     Xerox PARC
  22.     3333 Coyote Hill Rd.
  23.     Palo Alto, CA
  24.   endcopyright */
  25.  
  26. #include <sys/types.h>
  27. #include <sys/file.h>
  28. #include <sys/stat.h>
  29. #include <stdio.h>
  30. #include <errno.h>
  31. #include <stab.h>
  32. #include <ar.h>
  33. #include <sys/exec.h>
  34. #include <a.out.h>
  35. #undef relocation_info
  36. #define relocation_info reloc_info_sparc
  37. #include <xr/transform.h>
  38.  
  39. /*
  40.  * Transform_symtab reads a short ILsymtab.pidXXX file and produces an a.out file for dbx.
  41.  * Each line in the input file is either a common symbol definition or a pointer.
  42.  * A common symbol definition is simply appended to the output symbol table.
  43.  * A pointer (to an a.out file) will result in the symbol table of the pointed file
  44.  * being appended to the output symbol table with the following processing:
  45.  *    undefined symbols are deleted,
  46.  *    debugger symbols are deleted if the nodebugger flag for the pointer is true.
  47.  * For each symbol table appended to the output file, there is a string table kept
  48.  * in memory and written at the end.
  49.  */
  50.  
  51. struct stringTab {    /* structure to represent a string table */
  52.   int size;        /* size of string table including the count word */
  53.   char strings[1];
  54. };
  55.  
  56. struct stringListElem {        /* structure to link string tables together */
  57.   struct stringListElem *link;
  58.   struct stringTab *ptr;
  59. };
  60.  
  61. FILE *file;         /* output file handle */
  62. struct exec header;    /* output file header */
  63. long stringTabLen = 4;    /* size of the final string table */
  64. struct stringListElem *stringListHead;    /* pointer to head of list of string tables */
  65. struct stringListElem *stringListTail;    /* pointer to tail of list of string tables */
  66.  
  67. struct entry {        /* structure to hold info for one symbol table */
  68. /*  int nodebugger; */
  69.   long address;
  70.   long dataAddress;
  71.   long bssAddress;
  72.   long offset;
  73.   char *filename;
  74.   FILE *inFile;
  75.   struct exec ahdr;
  76.   long nsym;
  77.   struct nlist *symtab;
  78.   struct stringTab *stringtab;
  79. };
  80.  
  81. /*
  82.  * #define free(p) FREE(p)
  83.  * #define malloc(c) MALLOC(c)
  84.  */
  85.  
  86.  
  87. copy_main()
  88. {
  89.   char line[512];
  90.   
  91.   file = stdout;
  92.   write_header();    /* position past header, real header written at the end */
  93.   while (gets(line, sizeof(line), file) != 0) {
  94.     if (line[0] == 'F')
  95.       doPointer(line + 2, 0);
  96.     else if (line[0] == 'f')
  97.       doPointer(line + 2, 1);
  98.     else if (line[0] == 'C')
  99.       doCommonSymbolDefinition(line + 2);
  100.   }
  101.   doCommonSymbolDefinition(" 0 _theLastSymbol");
  102.   write_stringtab();
  103.   write_header();    /* write header info for real */
  104.   exit(0);
  105. }  /* copy_main */
  106.  
  107.  
  108. write_header()
  109. {
  110.   double zero;
  111.  
  112.   zero = 0;
  113.   header.a_text = sizeof(zero);
  114.   rewind(file);
  115.   fwrite(&header, sizeof(header), 1, file);
  116.   fwrite(&zero, sizeof(zero), 1, file);        /* dummy 'text' */  
  117. }  /* write_header */
  118.  
  119.  
  120. doCommonSymbolDefinition(line)
  121. char *line;
  122. {
  123.   struct nlist symbol;
  124.   char symbolName[512];
  125.   int size;
  126.   struct stringTab *strp;
  127.   char *cp;
  128.   
  129.   symbol.n_type = N_EXT | N_BSS;
  130.   symbol.n_other = 0;
  131.   symbol.n_desc = 0;
  132.   sscanf(line, SYMTAB_PID_COMMON_FORMAT, &symbol.n_value, symbolName);
  133.   cp = symbolName;
  134.   size = strlen(cp) + 1 + sizeof(int);
  135.   strp = (struct stringTab *)malloc(size);
  136.   
  137.   if (strp == 0) {
  138.       perror("Copy: doCommonSymbolDefinition: malloc failed");
  139.       exit(1);
  140.   }
  141.   
  142.   strp->size = size;
  143.   strcpy(strp->strings, cp);
  144.   symbol.n_un.n_strx = stringTabLen + sizeof(int);
  145.   
  146.   write_sym(&symbol);
  147.   appendStringTable(strp);
  148. }
  149.  
  150.  
  151. write_sym(p)
  152. struct nlist *p;
  153. {
  154.   fwrite(p, sizeof(struct nlist), 1, file);
  155.   header.a_syms += sizeof(struct nlist);
  156. }
  157.  
  158.  
  159. appendStringTable(strp)
  160. struct stringTab *strp;
  161. {
  162.   struct stringListElem *q;
  163.   
  164.   q = (struct stringListElem *)malloc(sizeof(struct stringListElem));
  165.   
  166.   if (q == 0) {
  167.       perror("Copy: appendStringTable: malloc failed");
  168.       exit(1);
  169.   }
  170.   
  171.   q->link = 0;
  172.   q->ptr = strp;
  173.   if (stringListHead == 0) {
  174.     stringListHead = stringListTail = q;
  175.   }
  176.   else {
  177.     stringListTail->link = q;
  178.     stringListTail = q;
  179.   }
  180.   stringTabLen += strp->size;
  181.   /* printf("strings - %d\n", strp->size); */
  182. }
  183.  
  184.  
  185. doPointer(line, nodebugger)
  186. char *line;
  187. {
  188.   struct entry e;
  189.   FILE *inFile, *open_file();
  190.   struct exec hdr;
  191.   int newstringlen, ii;
  192.   struct nlist *sp;
  193.   char symbolName[512];
  194.   char *cp;
  195.   struct stringTab *newstringtab;
  196.  
  197.   sscanf(line, SYMTAB_PID_FORMAT, &e.address,
  198.     &e.dataAddress, &e.bssAddress, &e.offset, symbolName);
  199.   e.filename = symbolName;
  200.   e.inFile = open_file(e.filename, &e.ahdr, e.offset);
  201.   read_symtab(&e);
  202.   fclose(e.inFile);
  203.   relocate_symtab(&e);
  204.   /*
  205.    * make one pass counting strings
  206.    */
  207.   for (newstringlen = sizeof(int), ii = 0; ii < e.nsym; ii++) {
  208.     sp = e.symtab + ii;
  209. #   define UNWANTED    ( ( ((sp->n_type & N_TYPE) == N_UNDF) && \
  210.                 (sp->n_type & N_EXT) \
  211.               ) || \
  212.               (nodebugger && (sp->n_type & N_STAB) \
  213.               ) \
  214.             )
  215.     if (UNWANTED) {
  216.       continue;
  217.     }
  218.     cp = (char *)e.stringtab + sp->n_un.n_strx;
  219.     newstringlen += strlen(cp) + 1;
  220.   }
  221.   if (newstringlen < e.stringtab->size) {
  222.     /* printf("string table may be reduced from %d to %d\n",
  223.         e.stringtab->size, newstringlen); */
  224.     newstringtab = (struct stringTab *)malloc(newstringlen);
  225.  
  226.     if (newstringtab == 0) {
  227.       perror("Copy: doPointer: malloc failed");
  228.       exit(1);
  229.     }
  230.  
  231.     newstringtab->size = sizeof(int);
  232.   }
  233.   else
  234.     newstringtab = 0;
  235.   /*
  236.    * write out symbols, constructing new string table if necessary
  237.    */
  238.   for (ii = 0; ii < e.nsym; ii++) {
  239.     sp = e.symtab + ii;
  240.     if (UNWANTED) {
  241.       continue;
  242.     }
  243.     if (newstringtab) {
  244.       cp = (char *)e.stringtab + sp->n_un.n_strx;
  245.       strcpy((char *)newstringtab + newstringtab->size, cp);
  246.       sp->n_un.n_strx = stringTabLen + newstringtab->size;
  247.       newstringtab->size += strlen(cp) + 1;
  248.       if (newstringtab->size > newstringlen)
  249.         printf("??? error copying strings %d %d\n",
  250.         newstringlen, newstringtab->size);
  251.     }
  252.     else {
  253.       sp->n_un.n_strx += stringTabLen;
  254.     }
  255.     write_sym(sp);
  256.   }
  257.   free(e.symtab);
  258.   if (newstringtab) {
  259.     free(e.stringtab);
  260.     appendStringTable(newstringtab);
  261.   }
  262.   else {
  263.     appendStringTable(e.stringtab);
  264.   }
  265. }
  266.  
  267.  
  268. FILE *
  269. open_file(filename, ahdr, offset)
  270. char *filename;
  271. struct exec *ahdr;
  272. {
  273.   FILE *returnval;
  274.   
  275.   /* fprintf(stderr, "opening `%s`\n", filename); */
  276.   if ((returnval = fopen(filename, "r")) == 0) {
  277.     fprintf(stderr, "Cannot open file '%s'.", filename);
  278.     exit(1);
  279.   }
  280.   fseek(returnval, offset, 0);
  281.   fread (ahdr, sizeof(struct exec), 1, returnval);
  282.   if (N_BADMAG(*ahdr)) {
  283.     fprintf(stderr, "magic is %d.\n", ahdr->a_magic);
  284.     exit(2);
  285.   }
  286.   if (header.a_magic == 0) {
  287.     header.a_dynamic = ahdr->a_dynamic;
  288.     header.a_toolversion = ahdr->a_toolversion;
  289.     header.a_machtype = ahdr->a_machtype;
  290.     header.a_magic = ahdr->a_magic;
  291.     header.a_magic = OMAGIC;
  292.   }
  293.   return returnval;
  294. }  /* open_file */
  295.  
  296.  
  297. read_symtab(p)
  298. struct entry *p;
  299. {
  300.   long string_len;
  301.   
  302.   p->nsym = p->ahdr.a_syms / sizeof(struct nlist);
  303.   
  304.   /*
  305.    *    Read in the symbol table
  306.    */
  307.   p->symtab = (struct nlist *)malloc(p->ahdr.a_syms);
  308.   
  309.   if (p->symtab == 0) {
  310.       perror("Copy: read_symtab: Read symbol table: malloc failed");
  311.       exit(1);
  312.   }
  313.  
  314.   fseek(p->inFile, p->offset + N_SYMOFF(p->ahdr), 0);
  315.   fread (p->symtab, sizeof (struct nlist), p->nsym, p->inFile);
  316.   /*
  317.    *    Read in the string table
  318.    */
  319.   fseek(p->inFile, p->offset + N_STROFF(p->ahdr), 0);
  320.   fread (&string_len, sizeof(string_len), 1, p->inFile);
  321.   if (string_len <= 0) {    
  322.     fprintf(stderr, "No string table."); 
  323.     exit(5);
  324.   }
  325.   p->stringtab = (struct stringTab *)malloc(string_len);
  326.     
  327.   if (p->stringtab == 0) {
  328.       perror("Copy: read_symtab: Read string table: malloc failed");
  329.       exit(1);
  330.   }
  331.  
  332.   fseek(p->inFile, p->offset + N_STROFF(p->ahdr), 0);
  333.   fread (p->stringtab, string_len, 1, p->inFile);
  334.   /* printf("strings + %d\n", string_len); */
  335. }  /* read_symtab */
  336.   
  337.  
  338. relocate_symtab(p)
  339. struct entry *p;
  340. {
  341.   int ii;
  342.   
  343.   for (ii = 0; ii < p->nsym; ii++) {
  344.     switch ((p->symtab[ii].n_type & N_TYPE)) {
  345.     case N_TEXT:
  346.       p->symtab[ii].n_value += p->address;
  347.       break;
  348.     case N_DATA:
  349.       p->symtab[ii].n_value += p->dataAddress - p->ahdr.a_text;
  350.       break;
  351.     case N_BSS:
  352.       p->symtab[ii].n_value += p->bssAddress - p->ahdr.a_text - p->ahdr.a_data;
  353.       break;
  354.     }
  355.   }
  356. }  /* relocate_symtab */
  357.  
  358.  
  359. write_stringtab()
  360. {
  361.   struct stringListElem *q;
  362.   struct stringTab *strp;
  363.   
  364.   /* printf("sum of all string table lengths = %d\n", stringTabLen); */
  365.   fwrite(&stringTabLen, sizeof(stringTabLen), 1, file);
  366.   for (q = stringListHead; q; q = q->link) {
  367.     strp = q->ptr;
  368.     /* printf("strings = %d\n", strp->size); */
  369.     fwrite(strp, strp->size, 1, file);
  370.   }
  371. }  /* write_stringtab */
  372.  
  373.  
  374. /*
  375.  * #undef free
  376.  * #undef malloc
  377.  */
  378.  
  379. FREE(p)
  380. {
  381.   free(p);
  382.   printf("%06x free\n", p);
  383. }
  384.  
  385. MALLOC(c)
  386. {
  387.   int ret;
  388.   
  389.   ret = malloc(c);
  390.   printf("%06x (%06x) malloc\n", ret, c);
  391.   return (ret);
  392. }
  393.